package com.shijie.service.impl;

import com.shijie.dto.JudgeDTO;
import com.shijie.entity.Submit;
import com.shijie.judgeBox.JudgeWorkerCreator;
import com.shijie.service.JudgeService;
import com.shijie.utlis.JsonUtils;
import com.shijie.vo.JudgeVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
@Service
@RequiredArgsConstructor
public class JudgeServiceImpl implements JudgeService {

    private final ExecutorService threadPools = Executors.newFixedThreadPool(10);

    private final JudgeWorkerCreator judgeWorkerCreator;


    @Override
    public JudgeVO judge(JudgeDTO judgeDTO) {
        String code = judgeDTO.getCode();
        Submit.CodeType codeType = judgeDTO.getCodeType();
        Class<?>[] allType = judgeDTO.getAllType();
        Path casePath = judgeDTO.getCasePath();
        Path resultPath = judgeDTO.getResultPath();

        Class<?>[] paramsType = Arrays.copyOf(allType, allType.length - 1);
        Class<?> resultType = allType[allType.length - 1];

        ArrayList<List<?>> params = JsonUtils.readJson4FilePath(casePath, new ArrayList<List<?>>(0));
        ArrayList<List<?>> results = JsonUtils.readJson4FilePath(resultPath, new ArrayList<List<?>>(0));

        log.info("params:【{}】", params);
        log.info("results:【{}】", results);

        /*Future<JudgeVO> future = threadPools.submit(() -> {
            log.info("--开始判题机");
            JudgeWorkerCreator.JudgeWorker judgeWorker = judgeWorkerCreator.createJudgeWorker(codeType);
            Integer[] useInfo = judgeWorker.working(code, codeType, paramsType, params, resultType, results);
            log.info("--判题结束");
            return JudgeVO.builder().useMilTime(useInfo[0]).useKbMemory(useInfo[1]).build();
        });
        try {
            return future.get();
        } catch (Exception e) {
            future.cancel(true);
            throw new JudgeException(e.getMessage());
        }*/

        log.info("--开始判题机");

        JudgeWorkerCreator.JudgeWorker judgeWorker = judgeWorkerCreator.createJudgeWorker(codeType);
        Integer[] useInfo = judgeWorker.working(code, codeType, paramsType, params, resultType, results);

        log.info("--判题结束");
        return JudgeVO.builder().useMilTime(useInfo[0]).useKbMemory(useInfo[1]).build();

    }

}
